import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
import _createClass from "@babel/runtime/helpers/esm/createClass";
import _assertThisInitialized from "@babel/runtime/helpers/esm/assertThisInitialized";
import _inherits from "@babel/runtime/helpers/esm/inherits";
import _createSuper from "@babel/runtime/helpers/esm/createSuper";
import _regeneratorRuntime from "@babel/runtime/regenerator";
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
import _template from "lodash/template";
import _omit from "lodash/omit";
import _forEach from "lodash/forEach";
import _isFunction from "lodash/isFunction";
import _isEmpty from "lodash/isEmpty";
import _map from "lodash/map";
import _join from "lodash/join";
import _inRange from "lodash/inRange";
import _isArray from "lodash/isArray";

var _dec, _class, _class2;

import React from 'react';
import { Form, Row, Col, Spin } from 'antd';
import intl from "../../../utils/intl";
import request from "../../../utils/request";
import { getCurrentOrganizationId, getResponse } from "../../../utils/utils";
import { getColLayout, getGetValuePropFunc, getGetValueFromEventFunc, getInitialValue, getComponentType, renderDisabledField, preProcessComponentProps, dealObjectProps // postProcessComponentProps,
} from "../utils";
import { fieldLabelProp, fieldNameProp, composeFormOmitProps } from "../config";
import { postDynamicFormProcessComponentProps } from "./utils";

function fetchGet(_x) {
  return _fetchGet.apply(this, arguments);
}

function _fetchGet() {
  _fetchGet = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(_ref) {
    var url, query, body;
    return _regeneratorRuntime.wrap(function _callee$(_context) {
      while (1) {
        switch (_context.prev = _context.next) {
          case 0:
            url = _ref.url, query = _ref.query, body = _ref.body;
            return _context.abrupt("return", request(url, {
              method: 'GET',
              query: query,
              body: body
            }));

          case 2:
          case "end":
            return _context.stop();
        }
      }
    }, _callee);
  }));
  return _fetchGet.apply(this, arguments);
}

function fetchPost(_x2) {
  return _fetchPost.apply(this, arguments);
}

function _fetchPost() {
  _fetchPost = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(_ref2) {
    var url, query, body;
    return _regeneratorRuntime.wrap(function _callee2$(_context2) {
      while (1) {
        switch (_context2.prev = _context2.next) {
          case 0:
            url = _ref2.url, query = _ref2.query, body = _ref2.body;
            return _context2.abrupt("return", request(url, {
              method: 'POST',
              query: query,
              body: body
            }));

          case 2:
          case "end":
            return _context2.stop();
        }
      }
    }, _callee2);
  }));
  return _fetchPost.apply(this, arguments);
}

function fetchPut(_x3) {
  return _fetchPut.apply(this, arguments);
} // const ComposeFormContext = React.createContext();


function _fetchPut() {
  _fetchPut = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(_ref3) {
    var url, query, body;
    return _regeneratorRuntime.wrap(function _callee3$(_context3) {
      while (1) {
        switch (_context3.prev = _context3.next) {
          case 0:
            url = _ref3.url, query = _ref3.query, body = _ref3.body;
            return _context3.abrupt("return", request(url, {
              method: 'PUT',
              query: query,
              body: body
            }));

          case 2:
          case "end":
            return _context3.stop();
        }
      }
    }, _callee3);
  }));
  return _fetchPut.apply(this, arguments);
}

var FormItem = Form.Item;
var queryUrlInterpolate = /{([\s\S]+?)}/g;
var DynamicForm = (_dec = Form.create({
  fieldNameProp: null
}), _dec(_class = (_class2 = /*#__PURE__*/function (_React$PureComponent) {
  _inherits(DynamicForm, _React$PureComponent);

  var _super = _createSuper(DynamicForm);

  function DynamicForm(props) {
    var _this;

    _classCallCheck(this, DynamicForm);

    _this = _super.call(this, props);
    _this.state = {
      ds: false,
      // 是否是从 queryUrl 加载数据
      dataSource: {},
      // 保存初始属性, 提交时 数据为 初始值和表单值的merge
      queryLoading: false,
      // fetch data loading
      saveLoading: false // save data loading

    };
    _this.query = _this.query.bind(_assertThisInitialized(_this));
    _this.reset = _this.reset.bind(_assertThisInitialized(_this));
    _this.submit = _this.submit.bind(_assertThisInitialized(_this));
    _this.getFormData = _this.getFormData.bind(_assertThisInitialized(_this));
    _this.getOrganizationParams = _this.getOrganizationParams.bind(_assertThisInitialized(_this)); // 获取租户id url 路径参数

    return _this;
  }

  _createClass(DynamicForm, [{
    key: "componentDidMount",
    value: function componentDidMount() {
      var _this$props = this.props,
          onRef = _this$props.onRef,
          form = _this$props.form,
          _this$props$dataSourc = _this$props.dataSource,
          dataSource = _this$props$dataSourc === void 0 ? {} : _this$props$dataSourc;
      var ds = this.state.ds; // 传递 this, 获取表单数据的方法, 校验并获取表单数据的方法 传递出去

      if (ds) {
        this.query();
      } else {
        form.setFieldsValue(dataSource);
      }

      if (_isFunction(onRef)) {
        onRef(this);
      }
    }
    /**
     * 渲染所有表单行
     */

  }, {
    key: "renderRows",
    value: function renderRows() {
      var _this$props2 = this.props,
          col = _this$props2.col,
          fields = _this$props2.fields,
          context = _this$props2.context,
          dataSource = _this$props2.dataSource,
          form = _this$props2.form;
      var contextFields = [];

      _forEach(fields, function (field) {
        if (field.visiableFlag === 1) {
          var contextField = dealObjectProps(field, context);
          contextField.props = preProcessComponentProps({
            field: contextField,
            context: context
          });
          contextFields.push(contextField);
        }
      });

      _forEach(contextFields, function (field) {
        postDynamicFormProcessComponentProps({
          fields: contextFields,
          field: field,
          dealProps: field.props,
          dataSource: dataSource,
          form: form
        });
      }); // 存放 生成的 Row


      var rows = []; // 所有的 字段的数组
      // 当前遍历的字段的下标

      var walkerIndex = 0; // 当前遍历的 Row 的 fields

      var rowFields = []; // 已经遍历的 Row 的 fields 的宽度和

      var rowCol = 0; // 当前遍历的 Row 的 field 的下标

      var rowIndex = 0;

      if (_isArray(contextFields)) {
        for (; walkerIndex < contextFields.length;) {
          var field = contextFields[walkerIndex];
          rowFields.push(field);

          if (_inRange(field.colspan, 2, col + 1)) {
            rowCol += field.colspan;
          } else {
            rowCol += 1;
          }

          if (_inRange(field.leftOffset, 1, col)) {
            rowCol += field.leftOffset;
          }

          if (_inRange(field.rightOffset, 1, col)) {
            rowCol += field.rightOffset;
          }

          if (rowCol >= col) {
            if (rowCol > col && rowIndex > 0) {
              // 已经超过一列的宽度了,并且字段多于1个 需要 回退
              walkerIndex--;
              rowFields.pop();
            } // 生成 Row 并放入 rows


            rows.push(this.renderRow({
              rowFields: rowFields
            })); // 重置 遍历的 Row 的状态

            rowIndex = 0;
            rowCol = 0;
            rowFields = [];
          } else {
            // 继续向前遍历
            rowIndex++;
          }

          walkerIndex++;
        }

        if (rowIndex > 0) {
          rows.push(this.renderRow({
            rowFields: rowFields
          }));
        }
      }

      return rows;
    }
    /**
     * 渲染表单行
     * @param {Object[]} rowFields - 一行对应的字段
     */

  }, {
    key: "renderRow",
    value: function renderRow(_ref4) {
      var _this2 = this;

      var rowFields = _ref4.rowFields;
      var wrapperFieldComponent = this.props.wrapperFieldComponent;
      return /*#__PURE__*/React.createElement(Row, {
        type: "flex",
        key: _join(_map(rowFields, function (field) {
          return field[fieldNameProp];
        }), '-')
      }, _map(rowFields, function (field) {
        if (_isFunction(wrapperFieldComponent)) {
          return wrapperFieldComponent(_this2.renderComposeFormField({
            field: field
          }), field);
        }

        return _this2.renderComposeFormField({
          field: field
        });
      }));
    }
    /**
     * 渲染最终的字段
     * @param {Object} field - 字段
     */

  }, {
    key: "renderComposeFormField",
    value: function renderComposeFormField(_ref5) {
      var field = _ref5.field;
      var _this$props3 = this.props,
          fieldLabelWidth = _this$props3.fieldLabelWidth,
          col = _this$props3.col,
          editable = _this$props3.editable,
          form = _this$props3.form;
      var dataSource = this.state.dataSource;
      var formItemProps = {
        labelCol: {
          style: {
            width: fieldLabelWidth,
            minWidth: fieldLabelWidth,
            maxWidth: fieldLabelWidth
          }
        },
        wrapperCol: {
          style: {
            flex: 'auto'
          }
        }
      };
      var colProps = getColLayout(col);
      var fieldColProps = getColLayout(col, field.colspan);
      var leftEmptyCols = [];
      var rightEmptyCols = [];

      if (_inRange(field.leftOffset, 1, col)) {
        for (var i = 0; i < field.leftOffset; i++) {
          leftEmptyCols.push( /*#__PURE__*/React.createElement(Col, Object.assign({}, colProps, {
            key: "".concat(field[fieldNameProp], "#left-offset-").concat(i)
          })));
        }
      }

      if (_inRange(field.rightOffset, 1, col)) {
        for (var _i = 0; _i < field.rightOffset; _i++) {
          rightEmptyCols.push( /*#__PURE__*/React.createElement(Col, Object.assign({}, colProps, {
            key: "".concat(field[fieldNameProp], "#right-offset-").concat(_i)
          })));
        }
      }

      var ComponentType = getComponentType(field);
      var otherFormItemOptions = {}; // 表单字段 omit 属性

      var componentProps = _omit(field.props, ['labelDisplayFlag']);

      var getValueFromEvent = getGetValueFromEventFunc(field.componentType);
      var getValueProps = getGetValuePropFunc(field);

      if (getValueFromEvent) {
        otherFormItemOptions.getValueFromEvent = getValueFromEvent;
      }

      if (getValueProps) {
        // 不影响存的值, 只影响传递给组件的值
        otherFormItemOptions.getValueProps = getValueProps;
      }

      var visible = field.visiableFlag !== 0;

      if (field.props.description) {
        formItemProps.extra = field.props.description;
      }

      var composeFormItem = editable ? visible ? /*#__PURE__*/React.createElement(Col, Object.assign({}, fieldColProps, {
        key: field[fieldNameProp]
      }), /*#__PURE__*/React.createElement(FormItem, Object.assign({
        label: field.props.labelDisplayFlag ? field[fieldLabelProp] : ''
      }, formItemProps, {
        required: field.requiredFlag !== 0
      }), form.getFieldDecorator(field[fieldNameProp], _objectSpread(_objectSpread({}, otherFormItemOptions), {}, {
        initialValue: getInitialValue({
          field: field,
          dataSource: dataSource
        }),
        rules: [{
          required: field.requiredFlag !== 0,
          message: intl.get('cpaas.common.validation.notNull', {
            name: field[fieldLabelProp]
          })
        }]
      }))( /*#__PURE__*/React.createElement(ComponentType, Object.assign({}, componentProps, {
        disabled: field.props.disabled || field.enabledFlag !== 1
      }))))) : null : /*#__PURE__*/React.createElement(Col, Object.assign({}, fieldColProps, {
        key: field[fieldNameProp]
      }), /*#__PURE__*/React.createElement(FormItem, Object.assign({
        label: field[fieldLabelProp]
      }, formItemProps), renderDisabledField({
        field: field,
        dataSource: dataSource,
        formItemProps: formItemProps,
        componentProps: field.props
      })));

      if (_isEmpty(leftEmptyCols) && _isEmpty(rightEmptyCols)) {
        return composeFormItem;
      }

      return /*#__PURE__*/React.createElement(React.Fragment, {
        key: field[fieldNameProp]
      }, leftEmptyCols, composeFormItem, rightEmptyCols);
    }
  }, {
    key: "render",
    value: function render() {
      var _this$props4 = this.props,
          _this$props4$editable = _this$props4.editable,
          editable = _this$props4$editable === void 0 ? false : _this$props4$editable,
          _this$props4$loading = _this$props4.loading,
          loading = _this$props4$loading === void 0 ? false : _this$props4$loading;
      var _this$state = this.state,
          queryLoading = _this$state.queryLoading,
          saveLoading = _this$state.saveLoading;

      var otherProps = _omit(this.props, composeFormOmitProps);

      return /*#__PURE__*/React.createElement(Spin, {
        spinning: loading || queryLoading || saveLoading
      }, /*#__PURE__*/React.createElement(Form, Object.assign({
        layout: "inline",
        className: editable ? 'compose-form' : 'compose-form-disabled'
      }, otherProps), this.renderRows()));
    }
  }, {
    key: "getOrganizationParams",
    value: function getOrganizationParams() {
      var organizationId = getCurrentOrganizationId();
      return {
        organizationId: organizationId
      };
    }
    /**
     * 加载数据
     */

  }, {
    key: "query",
    value: function query() {
      var _this3 = this;

      var params = this.props.params;
      var _this$state2 = this.state,
          ds = _this$state2.ds,
          queryUrlTemplate = _this$state2.queryUrlTemplate;

      if (ds) {
        this.setState({
          queryLoading: true
        });
        fetchGet({
          url: queryUrlTemplate(_objectSpread(_objectSpread({}, this.getOrganizationParams()), params)),
          query: params
        }).then(function (res) {
          var dataSource = getResponse(res) || {};
          var form = _this3.props.form;

          _this3.setState({
            dataSource: dataSource
          });

          form.setFieldsValue(dataSource);
        }).then(function () {
          _this3.setState({
            queryLoading: false
          });
        });
      }
    }
    /**
     * 重置表单
     */

  }, {
    key: "reset",
    value: function reset() {
      var form = this.props.form;
      form.resetFields();
    }
    /**
     * 提交表单
     */

  }, {
    key: "submit",
    value: function submit() {
      var _this4 = this;

      var _this$props5 = this.props,
          form = _this$props5.form,
          rowKey = _this$props5.rowKey;
      return new Promise(function (resolve, reject) {
        form.validateFields(function (err, data) {
          if (!err) {
            var _this4$props = _this4.props,
                submit = _this4$props.submit,
                submitUrl = _this4$props.submitUrl;
            var _this4$state$dataSour = _this4.state.dataSource,
                dataSource = _this4$state$dataSour === void 0 ? {} : _this4$state$dataSour;

            var submitData = _objectSpread(_objectSpread({}, dataSource), data);

            if (submitUrl) {
              // 通过
              var dynamicService = submitData[rowKey] ? fetchPut : fetchPost;

              _this4.setState({
                saveLoading: true
              });

              dynamicService({
                url: submitUrl,
                body: submitData
              }).then(function (res) {
                var hasError = getResponse(res);

                if (hasError) {
                  resolve();
                } else {
                  reject(res);
                }
              }).then(function () {
                _this4.setState({
                  saveLoading: false
                });
              });
            } else if (_isFunction(submit)) {
              return submit(submitData);
            }
          }
        });
      });
    }
  }, {
    key: "getFormData",
    value: function getFormData() {
      var _this5 = this;

      return new Promise(function (resolve, reject) {
        var form = _this5.props.form;
        form.validateFields(function (err, fieldsValue) {
          var _this5$state$dataSour = _this5.state.dataSource,
              dataSource = _this5$state$dataSour === void 0 ? {} : _this5$state$dataSour;

          if (err) {
            reject(err);
          }

          resolve(_objectSpread(_objectSpread({}, dataSource), fieldsValue));
        });
      });
    }
  }], [{
    key: "getDerivedStateFromProps",
    value: function getDerivedStateFromProps(nextProps, prevState) {
      var nextState = {};

      if (prevState.queryUrl !== nextProps.queryUrl) {
        if (nextProps.queryUrl) {
          nextState.ds = true;
          nextState.queryUrlTemplate = _template(nextProps.queryUrl, {
            interpolate: queryUrlInterpolate
          });
        } else {
          nextState.ds = false;
          nextState.queryUrlTemplate = undefined;
        }

        nextState.queryUrl = nextProps.queryUrl;
      }

      if (nextProps.dataSource) {
        if (nextProps.dataSource !== prevState.dataSource) {
          nextState.dataSource = nextProps.dataSource;
        }
      }

      return nextState;
    }
  }]);

  return DynamicForm;
}(React.PureComponent), _class2.defaultProps = {
  // 默认的属性
  col: 3,
  fields: [],
  editable: false,
  fieldLabelWidth: 150,
  context: undefined
}, _class2)) || _class);
export { DynamicForm as default }; // 暴露出去的方法

DynamicForm.exportFuncs = ['submit', 'reset'];
DynamicForm.exportFuncsInfo = {
  submit: {
    descriptionIntlCode: 'cpfm.ui.tpl.form.submit',
    descriptionIntlDefault: intl.get('cpaas.common.button.submit').d('提交')
  },
  reset: {
    descriptionIntlCode: 'cpfm.ui.tpl.form.reset',
    descriptionIntlDefault: intl.get('cpaas.common.button.reset').d('重置')
  }
};